/*
 * Copyright (c) 2017 LingoChamp Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.liulishuo.okdownload.core.file;

import com.liulishuo.okdownload.core.LogUtillib;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.app.Context;
import ohos.utils.net.Uri;

import java.io.*;
import java.nio.channels.FileChannel;

public class DownloadUriOutputStream implements DownloadOutputStream {


    private final FileChannel channel;
    FileDescriptor pdf;
    final BufferedOutputStream out;
    FileOutputStream fos;

    public DownloadUriOutputStream(Context context, Uri uri, int bufferSize) {
        FileDescriptor pdf = null;
        try {
            pdf = DataAbilityHelper.creator(context).openFile(uri, "rw");
        } catch (Exception e) {
            LogUtillib.e("Download", e.getMessage());
        }
        this.pdf = pdf;
        this.fos = new FileOutputStream(pdf);
        this.channel = fos.getChannel();
        this.out = new BufferedOutputStream(fos, bufferSize);
    }

    public DownloadUriOutputStream(Context context, File file, int bufferSize) {
        try {
            this.fos = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            LogUtillib.e("DownloadUriOutputStream", e.getMessage());
        }
        this.channel = fos.getChannel();
        this.out = new BufferedOutputStream(fos, bufferSize);
    }

    @Override
    public void write(byte[] b, int off, int len) throws IOException {
        out.write(b, off, len);
    }

    @Override
    public void close() throws IOException {
        out.close();
        fos.close();
    }

    @Override
    public void flushAndSync() throws IOException {
        out.flush();
        fos.flush();
        if (pdf != null) {
            pdf.sync();
        }
    }

    @Override
    public void seek(long offset) throws IOException {
        channel.position(offset);
    }

    @Override
    public void setLength(long newLength) {
        //todo 暂时删除，无用
//        try {
//            OsHelper.allocSpaceForFile(pdf, 0, newLength);
//        } catch (OsHelperErrnoException e) {
//            e.printStackTrace();
//            try {
//                OsHelper.trimFile(newLength, pdf);
//            } catch (OsHelperErrnoException ex) {
//                ex.printStackTrace();
//            }
//        }
    }

    public static class Factory implements DownloadOutputStream.Factory {

        @Override
        public DownloadOutputStream create(Context context, File file, int flushBufferSize) {
            return new DownloadUriOutputStream(context, file, flushBufferSize);
        }

        @Override
        public DownloadOutputStream create(Context context, Uri uri, int flushBufferSize) {
            return new DownloadUriOutputStream(context, uri, flushBufferSize);
        }

        @Override
        public boolean supportSeek() {
            return true;
        }
    }
}
